package user.service.Impl;

import com.spring4all.spring.boot.starter.hbase.api.HbaseTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.LongComparator;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import user.contstant.Constants;
import user.dao.MerchantsDao;
import user.entity.Merchants;
import user.mapper.PassTemplateRowMapper;
import user.service.IInventoryService;
import user.service.IUserPassService;
import user.util.RowKeyGenUtil;
import user.vo.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 获取库存信息，只返回用户没有领取的
 */
@Service
@Slf4j
public class InventoryServiceImpl implements IInventoryService {

    /**HBase 客户端*/
    private final HbaseTemplate hbaseTemplate;
    private final MerchantsDao merchantsDao;
    private final IUserPassService iUserPassService;
    @Autowired
    public InventoryServiceImpl(HbaseTemplate hbaseTemplate,
                                MerchantsDao merchantsDao,
                                IUserPassService iUserPassService) {
        this.hbaseTemplate = hbaseTemplate;
        this.merchantsDao = merchantsDao;
        this.iUserPassService = iUserPassService;
    }

    /**
     * 获取库存信息
     * @param userId 用户id
     * @return  {@link Response}
     * @throws Exception
     */
    @Override
    public Response getInventoryInfo(Long userId) throws Exception {

        /**获取用户领取的所有优惠券*/
        Response allUserPass = iUserPassService.getUserAllPassInfo(userId);
        //获取passInfo
        List<PassInfo> passInfos = (List<PassInfo>) allUserPass.getData();
        /**获取需要排除的passTemplate*/
        List<PassTemplate> exclude = passInfos.stream().map(
                PassInfo :: getPassTemplate
        ).collect(Collectors.toList());

        List<String> excludeIds = new ArrayList<>();

        //获取需要排除的passTemplateId
        exclude.forEach(e ->  excludeIds.add(
                RowKeyGenUtil.genPassTemplateRowKey(e)
        ));

        return new Response(new InventoryResponse(
                userId,buildPassTemplateInfo(getAvailablePassTemplate(excludeIds))));
    }

    /**
     * 获取系统中可用的优惠券
     * @param excludeIds 需要排除的优惠券 ids
     * @return {@link PassTemplate}
     */
    private List<PassTemplate> getAvailablePassTemplate(List<String> excludeIds){

        //设置过滤器
        FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE);
        filterList.addFilter(
                new SingleColumnValueFilter(
                        Bytes.toBytes(Constants.PassTemplateTable.FAMILY_C),
                        Bytes.toBytes(Constants.PassTemplateTable.LIMIT),
                        CompareFilter.CompareOp.GREATER,
                        new LongComparator(0L)
                )
        );
        filterList.addFilter(
                new SingleColumnValueFilter(
                        Bytes.toBytes(Constants.PassTemplateTable.FAMILY_C),
                        Bytes.toBytes(Constants.PassTemplateTable.LIMIT),
                        CompareFilter.CompareOp.EQUAL,
                        Bytes.toBytes("-1")
                )
        );

        //扫描器
        Scan scan = new Scan();
        scan.setFilter(filterList);

        //查询获取优惠券列表
        List<PassTemplate> validTemplates = hbaseTemplate.find(
                Constants.PassTemplateTable.TABLE_NAME,scan,new PassTemplateRowMapper());
        //结果集
        List<PassTemplate> availablePassTemplates = new ArrayList<>();
        //过滤优惠券,过期时间，需要排除的优惠券 ids
        Date cur = new Date();
        for(PassTemplate ps : validTemplates){
            if(excludeIds.contains(RowKeyGenUtil.genPassTemplateRowKey(ps)))
                continue;
            if(cur.getTime() >= ps.getStart().getTime() && cur.getTime() <= ps.getEnd().getTime())
                availablePassTemplates.add(ps);
        }
        return availablePassTemplates;
    }

    /**
     * 构造优惠券的信息
     * @param passTemplates {@link PassTemplate}
     * @return {@link PassTemplateInfo}
     */
    private List<PassTemplateInfo> buildPassTemplateInfo(List<PassTemplate> passTemplates){

        Map<Integer, Merchants> merchantsMap = new HashMap<>();
        //获取商户id
        List<Integer> merchantsIds = passTemplates.stream().map(
           PassTemplate::getId
        ).collect(Collectors.toList());

        //获取商户对象
        List<Merchants> merchants = merchantsDao.findByIdIn(merchantsIds);
        //将商户添加到map对象
        merchants.forEach(m -> merchantsMap.put(m.getId(),m));

        List<PassTemplateInfo> result = new ArrayList<>(passTemplates.size());

        for(PassTemplate passTemplate : passTemplates){

            //获取商户对象
            Merchants mc = merchantsMap.getOrDefault(passTemplate.getId(),null);
            //判断是否为空
            if(mc == null){
                log.error("merchants error : {}",passTemplate.getId());
                continue;
            }
            result.add(new PassTemplateInfo(passTemplate,mc));
        }
        return result;
    }
}
